package com.leoman.welfareapi.service.impl;

import com.leoman.entity.Configue;
import com.leoman.entity.Constant;
import com.leoman.exception.*;
import com.leoman.giftrecord.dao.GiftExchangeRecordDao;
import com.leoman.giftrecord.entity.GiftExchangeRecord;
import com.leoman.image.dao.ExpressionDao;
import com.leoman.image.entity.Expressions;
import com.leoman.image.entity.vo.ExpressionVo;
import com.leoman.indexapi.service.UserTaskApiService;
import com.leoman.reourceapi.service.impl.ResourceApiServiceImpl;
import com.leoman.systemsetting.dao.PrizeDao;
import com.leoman.systemsetting.entity.Prize;
import com.leoman.user.dao.UserInfoDao;
import com.leoman.user.dao.UserIntegralDao;
import com.leoman.user.entity.UserInfo;
import com.leoman.userapi.service.UserIntegralService;
import com.leoman.utils.DateUtils;
import com.leoman.utils.ImageUtil;
import com.leoman.welfare.dao.UserLotteryDao;
import com.leoman.welfare.dao.UserWelfareCountDao;
import com.leoman.welfare.dao.UserWelfareDao;
import com.leoman.welfare.dao.WelfareDao;
import com.leoman.welfare.entity.UserLottery;
import com.leoman.welfare.entity.UserWelfare;
import com.leoman.welfare.entity.UserWelfareCount;
import com.leoman.welfare.entity.Welfare;
import com.leoman.welfareapi.service.WelfareApiService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * 福利实现类
 * Created by tuyh on 2016/6/12.
 */
@Service
public class WelfareApiServiceImpl implements WelfareApiService {

    @Autowired
    private WelfareDao welfareDao;

    @Autowired
    private UserInfoDao userInfoDao;

    @Autowired
    private GiftExchangeRecordDao giftExchangeRecordDao;

    @Autowired
    private PrizeDao prizeDao;

    @Autowired
    private UserLotteryDao userLotteryDao;

    @Autowired
    private UserWelfareDao userWelfareDao;

    @Autowired
    private UserIntegralService userIntegralService;

    @Autowired
    private UserIntegralDao userIntegralDao;

    @Autowired
    private ExpressionDao expressionDao;

    @Autowired
    private UserWelfareCountDao userWelfareCountDao;

    @Autowired
    private UserTaskApiService userTaskApiService;

    @Override
    public Page<Welfare> iPage(Integer pageNum, Integer pageSize) {
        int[] info = ResourceApiServiceImpl.changePageParams(pageNum, pageSize);
        Page<Welfare> page = welfareDao.findAll(new PageRequest(info[0] - 1, info[1], Sort.Direction.DESC, "status", "updateDate"));

        String path;
        for (Welfare welfare : page.getContent()) {
            welfare.setCover(ImageUtil.clearUploadUrl(welfare.getCover()));

            if (StringUtils.isNotBlank(welfare.getUrl())) {
                path = welfare.getUrl().replaceAll(Configue.getUploadUrls(), "");
                if (!path.contains("http")) {
                    welfare.setUrl(Configue.getUploadUrls() + path);
                } else {
                    welfare.setUrl(path);
                }
            }
        }

        return page;
    }

    @Override
    public Welfare iFindOne(Long id) throws ParamsErrorException {
        if (null == id) {
            throw new ParamsErrorException();
        }
        Welfare welfare = welfareDao.findOne(id);
        welfare.setCover(ImageUtil.clearUploadUrl(welfare.getCover()));
        welfare.setSuolue(ImageUtil.clearUploadUrl(welfare.getSuolue()));
        if (StringUtils.isNotBlank(welfare.getUrl())) {
            String path = welfare.getUrl().replaceAll(Configue.getUploadUrls(), "");
            if (!path.contains("http")) {
                welfare.setUrl(Configue.getUploadUrls() + path);
            } else {
                welfare.setUrl(path);
            }
        }

        // 统计福利浏览量
        userTaskApiService.addWelfareData(welfare, 1);

        return welfare;
    }

    @Override
    @Transactional
    public void exchangeWelfare(Long userId, Long welfareId, String nickname, String mobile, String address) throws ParamsErrorException, WelfareNotFindException, UserNotFindException, BreadShortException, WelfareTimeErrorException, WelfareStoreNumErrorException, UserLevelErrorException, UserWelfareCountErrorException {
        if (null == userId || null == welfareId || !StringUtils.isNotEmpty(nickname) || !StringUtils.isNotEmpty(mobile) || !StringUtils.isNotEmpty(address)) {
            throw new ParamsErrorException();
        }

        Welfare welfare = welfareDao.findOne(welfareId);
        if (null == welfare) {
            throw new WelfareNotFindException();
        }

        // 判断兑换次数是否已达上限
        UserWelfareCount userWelfareCount = userWelfareCountDao.findOneByUserIdAndWelfareId(userId, welfareId);
        if (null != userWelfareCount && userWelfareCount.getCount() >= welfare.getChangeNum()) {
            throw new UserWelfareCountErrorException();
        }

        // 判断库存是否足够
        if (welfare.getStoreNum() < 1) {
            throw new WelfareStoreNumErrorException();
        }

        // 判断时间是否在开始时间和结束时间之间，如果不在，返回错误
        Long nowTime = System.currentTimeMillis();
        if (welfare.getStartDate() > nowTime || welfare.getEndDate() < nowTime) {
            throw new WelfareTimeErrorException();
        }

        UserInfo userInfo = userInfoDao.findOne(userId);
        if (null == userInfo) {
            throw new UserNotFindException();
        }

        // 判断用户等级是否足够
        if (welfare.getConditions() > userInfo.getLevel()) {
            throw new UserLevelErrorException();
        }

        if (userInfo.getCoin() < welfare.getCoin()) {
            throw new BreadShortException();
        }

        // 修改兑换数
        welfare.setNum(welfare.getNum() + 1);
        welfare.setStoreNum(welfare.getStoreNum() - 1);
        welfareDao.save(welfare);

        // 修改用户剩余馒头数
        userIntegralService.changeCoin(userInfo, "兑换福利 " + welfare.getTitle(), welfare.getCoin() * -1);

        // 增加兑换记录
        UserWelfare userWelfare = new UserWelfare();
        userWelfare.setUserInfo(userInfo);
        userWelfare.setWelfare(welfare);

        userWelfareDao.save(userWelfare);

        GiftExchangeRecord giftExchangeRecord = new GiftExchangeRecord();
        giftExchangeRecord.setUserInfo(userInfo);
        giftExchangeRecord.setNickname(userInfo.getNickname());
        giftExchangeRecord.setMobile(userInfo.getMobile());
        giftExchangeRecord.setGiftName(welfare.getTitle());
        giftExchangeRecord.setType(welfare.getType());
        giftExchangeRecord.setExchangeCoin(welfare.getCoin());
        giftExchangeRecord.setReceiverName(nickname);
        giftExchangeRecord.setReceiverMobile(mobile);
        giftExchangeRecord.setReceiverAddress(address);
        giftExchangeRecord.setStatus(0);

        giftExchangeRecordDao.save(giftExchangeRecord);

        saveUserWelfareCountInfo(userWelfareCount, userInfo, welfare);
    }

    @Override
    @Transactional
    public ExpressionVo exchangePlus(Long userId, Long welfareId) throws ParamsErrorException, UserNotFindException, WelfareNotFindException, BreadShortException, IntegralExchangeException, ExpressionExistException, WelfareTimeErrorException, WelfareStoreNumErrorException, UserLevelErrorException, UserWelfareCountErrorException {
        if (null == userId || null == welfareId) {
            throw new ParamsErrorException();
        }

        Welfare welfare = welfareDao.findOne(welfareId);
        if (null == welfare) {
            throw new WelfareNotFindException();
        }

        // 判断兑换次数是否已达上限
        UserWelfareCount userWelfareCount = userWelfareCountDao.findOneByUserIdAndWelfareId(userId, welfareId);
        if (null != userWelfareCount && userWelfareCount.getCount() >= welfare.getChangeNum()) {
            throw new UserWelfareCountErrorException();
        }

        // 判断库存是否足够
        if (welfare.getStoreNum() < 1) {
            throw new WelfareStoreNumErrorException();
        }

        // 判断时间是否在开始时间和结束时间之间，如果不在，返回错误
        Long nowTime = System.currentTimeMillis();
        if (welfare.getStartDate() > nowTime || welfare.getEndDate() < nowTime) {
            throw new WelfareTimeErrorException();
        }

        UserInfo userInfo = userInfoDao.findOne(userId);
        if (null == userInfo) {
            throw new UserNotFindException();
        }

        // 判断用户等级是否足够
        if (welfare.getConditions() > userInfo.getLevel()) {
            throw new UserLevelErrorException();
        }

        if (userInfo.getCoin() < welfare.getCoin()) {
            throw new BreadShortException();
        }

        // 如果兑换的是经验值，则当天兑换未到100修改用户经验值
        String context = "馒头兑换经验值";     // 和action_type字段挂钩,改的时候注意看下changeIntegral方法里面的String 一起改一下
        if (welfare.getType().equals(Constant.WELFARE_TYPE_001)) {
            Integer integer = userIntegralDao.findTodayExchangeIntegral(userId, DateUtils.getTimesmorning(), DateUtils.getTimesnight()) == null ? 0 : userIntegralDao.findTodayExchangeIntegral(userId, DateUtils.getTimesmorning(), DateUtils.getTimesnight());
            if (welfare.getExper() + integer <= 100) {
                // 获取经验值
                userIntegralService.changeIntegral(userInfo, context, welfare.getExper());
                // 修改兑换数
                welfare.setNum(welfare.getNum() + 1);
                welfare.setStoreNum(welfare.getStoreNum() - 1);
                welfareDao.save(welfare);

                // 修改用户剩余馒头数
                userIntegralService.changeCoin(userInfo, context, welfare.getCoin() * -1);

                UserWelfare userWelfare = new UserWelfare();
                userWelfare.setUserInfo(userInfo);
                userWelfare.setWelfare(welfare);

                userWelfareDao.save(userWelfare);
            } else {
                //超过当天兑换上限(100)
                throw new IntegralExchangeException();
            }
        } else {
            // 表情包只能兑换一次
            if (welfare.getType().equals(Constant.WELFARE_TYPE_003)) {
                List<UserWelfare> userWelfareList = userWelfareDao.findListByUserIdAndWelfareId(userId, welfareId);
                if (null == userWelfareList || userWelfareList.size() <= 0) {
                    // 修改兑换数
                    welfare.setNum(welfare.getNum() + 1);
                    welfare.setStoreNum(welfare.getStoreNum() - 1);
                    welfareDao.save(welfare);

                    // 修改用户剩余馒头数
                    userIntegralService.changeCoin(userInfo, "兑换表情包 " + welfare.getTitle(), welfare.getCoin() * -1);

                    UserWelfare userWelfare = new UserWelfare();
                    userWelfare.setUserInfo(userInfo);
                    userWelfare.setWelfare(welfare);

                    userWelfareDao.save(userWelfare);
                } else {
                    throw new ExpressionExistException();
                }
            }
        }

        GiftExchangeRecord giftExchangeRecord = new GiftExchangeRecord();
        giftExchangeRecord.setUserInfo(userInfo);
        giftExchangeRecord.setNickname(userInfo.getNickname());
        giftExchangeRecord.setMobile(userInfo.getMobile());
        giftExchangeRecord.setGiftName(welfare.getTitle());
        giftExchangeRecord.setType(welfare.getType());
        giftExchangeRecord.setExchangeCoin(welfare.getCoin());
        giftExchangeRecord.setStatus(2);

        giftExchangeRecordDao.save(giftExchangeRecord);

        saveUserWelfareCountInfo(userWelfareCount, userInfo, welfare);

        ExpressionVo expressionVo = new ExpressionVo();
        if (welfare.getType().equals(Constant.WELFARE_TYPE_003)) {
            // 拼接表情包信息
            List<Expressions> expressionList = expressionDao.findListByParentId(welfare.getId());

            expressionVo.setId(welfare.getId());
            expressionVo.setName(welfare.getTitle());
            if (null != expressionList && expressionList.size() > 0) {
                for (Expressions expressions1 : expressionList) {
                    expressions1.setParentId(expressions1.getParentId());
                    expressions1.setGifUrl(ImageUtil.clearUploadUrl(expressions1.getGifUrl().replace("\\", "/")));
                    expressions1.setPngUrl(ImageUtil.clearUploadUrl(expressions1.getPngUrl().replace("\\", "/")));
                }
                expressionVo.setThumbnail(expressionList.get(0).getPngUrl());
                expressionVo.setExpressionList(expressionList);
            }
        }

        return expressionVo;
    }

    private void saveUserWelfareCountInfo(UserWelfareCount userWelfareCount, UserInfo userInfo, Welfare welfare) {
        if (null == userWelfareCount) {
            userWelfareCount = new UserWelfareCount();
            userWelfareCount.setUserInfo(userInfo);
            userWelfareCount.setWelfare(welfare);
            userWelfareCount.setCount(1);
        } else {
            userWelfareCount.setCount(userWelfareCount.getCount() + 1);
        }

        userWelfareCountDao.save(userWelfareCount);
    }

    @Override
    public Page<GiftExchangeRecord> iPageExchange(Long userId, Integer pageNum, Integer pageSize) {
        int[] info = ResourceApiServiceImpl.changePageParams(pageNum, pageSize);
        return giftExchangeRecordDao.findListByUserId(userId, new PageRequest(info[0] - 1, info[1]));
    }

    @Override
    public List<Prize> probabilityList() {
        return prizeDao.findAll();
    }

    @Override
    @Transactional
    public Long lottery(Long userId, Integer status, Long lotteryId) throws UserNotFindException, BreadShortException, PrizeNotFindException {
        if (null == userId) {
            throw new UserNotFindException();
        }

        UserInfo userInfo = userInfoDao.findOne(userId);

        if (null == userInfo) {
            throw new UserNotFindException();
        }

        Long tempCoin = userInfo.getCoin();

        if (userInfo.getCoin() < Constant.DEFAULT_COIN) {
            throw new BreadShortException();
        }

        // 增加抽奖记录
        UserLottery userLottery = new UserLottery();
        userLottery.setUserInfo(userInfo);
        userLottery.setContent("抽奖");
        userLottery.setCoin(Constant.DEFAULT_COIN * -1);
        userLotteryDao.save(userLottery);

        // 增加馒头变动记录
        userIntegralService.changeCoin(userInfo, "抽奖", Constant.DEFAULT_COIN * -1);

        tempCoin = tempCoin - Constant.DEFAULT_COIN;

        // 中奖
        if (null != status && status == 1) {
            Prize prize = prizeDao.findOne(lotteryId);
            if (null == prize) {
                throw new PrizeNotFindException();
            }

            // 增加中奖记录
            userLottery = new UserLottery();
            userLottery.setUserInfo(userInfo);
            userLottery.setContent("中奖");
            userLottery.setCoin(prize.getCoin());
            userLotteryDao.save(userLottery);

            // 增加馒头变动记录
            userIntegralService.changeCoin(userInfo, "中奖", prize.getCoin());

            tempCoin += prize.getCoin();
        }

        return tempCoin;
    }

    @Override
    public Page<UserLottery> lotteryPage(Long userId, Integer pageNum, Integer pageSize) {
        int[] info = ResourceApiServiceImpl.changePageParams(pageNum, pageSize);
        return userLotteryDao.iPageByUserId(userId, new PageRequest(info[0] - 1, info[1]));
    }

    @Override
    public List<ExpressionVo> expressionList(Long userId) {
        List<ExpressionVo> list = new ArrayList<>();
        List<Expressions> expressionListPlus;
        ExpressionVo expressionVo;
        Welfare welfare;

        try {
            // 拼接表情包信息
            List<Expressions> expressionList = expressionDao.findList(userId);

            for (Expressions expressions : expressionList) {
                welfare = welfareDao.findOne(expressions.getParentId());
                expressionListPlus = expressionDao.findListByParentId(expressions.getParentId());
                expressionVo = new ExpressionVo();
                expressionVo.setId(welfare.getId());
                expressionVo.setName(welfare.getTitle());
                if (null != expressionListPlus && expressionListPlus.size() > 0) {
                    for (Expressions expressions1 : expressionListPlus) {
                        expressions1.setGifUrl(ImageUtil.clearUploadUrl(expressions1.getGifUrl().replace("\\", "/")));
                        expressions1.setPngUrl(ImageUtil.clearUploadUrl(expressions1.getPngUrl().replace("\\", "/")));
                    }

                    expressionVo.setThumbnail(expressionListPlus.get(0).getPngUrl());
                    expressionVo.setExpressionList(expressionListPlus);
                }

                list.add(expressionVo);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return list;
    }
}
